#include "dashboard.h"
#include "ui_dashboard.h"
#include <QPainter>
#include <QtMath>
#include <QDebug>

Dashboard::Dashboard(QWidget *parent)
	: QWidget(parent)
    , ui(new Ui::Dashboard)
{
	ui->setupUi(this);
	timer.setInterval(10);
	connect(&timer, SIGNAL(timeout()), this, SLOT(timeOut()));
}

Dashboard::Dashboard(int minValue, int tickValue, int tick, int value, QString text, QWidget *parent)
    : Dashboard(parent)
{
	set(minValue, tickValue, tick, value, text);
}

Dashboard::~Dashboard()
{
    delete ui;
}

void Dashboard::set(int minValue, int tickValue, int tick, int value, QString text)
{
	this->minValue = minValue;
	this->tickValue = tickValue;
	this->tick = tick;
	this->value = value;
	this->text = text; 
	arrowAngle = valueToAngle(this->value);
}

void Dashboard::setValue(int value)
{
    targetAngle = valueToAngle(value);
    frameValue = (targetAngle - arrowAngle)/100.0;
    this->value = value;
    if(!timer.isActive()){
        timer.start();
    }
    index = 0;
}

void Dashboard::setText(QString text)
{
    this->text=text;
    update();
}

double Dashboard::valueToAngle(int value)
{
    return 300.0/tick*((value-minValue)/tickValue)+300.0/tick/10.0*((value-minValue)%tickValue) + 120;
}

void Dashboard::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    double radius = qMin<int>(this->width(),this->height())/2-5;
    QPoint center = QPoint(this->width()/2, this->height()/2);
    painter.setBrush(QBrush(Qt::black));
    painter.drawEllipse(center, (int)radius, (int)radius);

    painter.setPen(QPen(Qt::white));
    QFont font;
    int pixelSize = int(radius/7);
    font.setPixelSize(pixelSize);
    painter.setFont(font);
    QTextOption option;
    option.setAlignment(Qt::AlignCenter);

    painter.translate(center);
    painter.rotate(90);
    for(int i=0;i<=tick;i++){
        double angle =300.0/tick;
        painter.rotate(angle);
        painter.drawLine(QPoint(radius*0.8, 0), QPoint(radius*0.9, 0));
        if(i!=tick){
            painter.save();
            for(int j=0;j<9;j++) {
                double angle2 = 300.0/tick/10.0;
                painter.rotate(angle2);
                painter.drawLine(QPoint(radius*0.85, 0), QPoint(radius*0.9, 0));
            }
            painter.restore();
        }

    }
    painter.rotate(-60);
    for(int i=0;i<=tick;i++) {
        double angle =(120.0 + 300.0/tick*i)/180.0*M_PI;
        QPoint p3 = QPoint(radius*0.7*qCos(angle),radius*0.7*qSin(angle));
        QRectF r = QRectF(p3-QPoint(pixelSize,pixelSize),p3+QPoint(pixelSize,pixelSize));
        painter.drawText(r, QString::number(minValue + tickValue*i),option);
    }

    double angle =M_PI/2;
    QPoint p = QPoint(radius*0.5*qCos(angle),radius*0.5*qSin(angle));
    QRectF r = QRectF(p-QPoint(radius,radius),p+QPoint(radius,radius));
    painter.drawText(r, text, option);

    p = QPoint(radius*0.8*qCos(angle),radius*0.8*qSin(angle));
    r = QRectF(p-QPoint(radius,radius),p+QPoint(radius,radius));
    painter.drawText(r, QString::number(value), option);
    painter.rotate(arrowAngle);

    drawArrow(painter);

    QWidget::paintEvent(event);
}

void Dashboard::drawArrow(QPainter &painter)
{
    double radius = qMin<int>(this->width(),this->height())/2-5;
    QColor color(Qt::white);
    painter.setBrush(QBrush(color));
    QPen pen = painter.pen();
    pen.setColor(color);
    painter.setPen(pen);
    painter.drawEllipse(QPoint(0,0), int(radius*0.1), int(radius*0.1));
    QPolygon polygon;
    polygon.push_back(QPoint(-(radius*0.2),-(radius*0.04)));
    polygon.push_back(QPoint(-(radius*0.2),(radius*0.04)));
    polygon.push_back(QPoint(radius*0.9,0));
    painter.drawPolygon(polygon);
}

void Dashboard::timeOut()
{
    if(arrowAngle==targetAngle) {
        timer.stop();
        return;
    }
    index ++;
    if(index==100) {
        arrowAngle = targetAngle;
    } else {
        arrowAngle+= frameValue;
    }
    update();
}
